﻿using System;
using System.Net;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DXTools.UI.Core.ViewModel;
using DXTools.Core.CrmSdk;

namespace DXTools.UI.Modules.ODataQueryDesigner.Model
{
    public class FilterClass : ViewModelBase
    {
        public FilterClass()
        {
            LogicalOperator = "AND";
            LogicalOperators = new string[2];
            LogicalOperators[0] = "AND";
            LogicalOperators[1] = "OR";
        }

        public AttributeClass[] Attributes { get; set; }
        public string Value { get; set; }
        private string _filterOperator { get; set; }
        public string LogicalOperator { get; set; }
        public string[] LogicalOperators { get; set; }
        public bool IsSelected { get; set; }
        public bool IsPrimaryGroupAttribute { get; set; }
        public bool IsFinalGroupAttribute { get; set; }
        public string _groupLogicalOperator;



        public event EventHandler FilterAttributeSelectedEvent;
        public event EventHandler DeleteFilterEvent;
        public event EventHandler UnGroupFiltersEvent;

        public AttributeClass SelectedAttribute
        {
            get { return _attributeSelected; }
            set
            {
                if (_attributeSelected != value)
                {
                    _attributeSelected = value;
                    Value = "";

                    if (_attributeSelected != null)
                    {
                        FilterOperators = new ObservableCollection<string>();

                        FilterOperators.Add("Equals");
                        FilterOperators.Add("Does Not Equal");

                        switch (_attributeSelected.AttributeType.Value)
                        {
                            case AttributeTypeCode.String:
                            case AttributeTypeCode.Memo:
                                FilterOperators.Add("Contains");
                                FilterOperators.Add("Does Not Contain");
                                FilterOperators.Add("Begins With");
                                FilterOperators.Add("Does Not Begin With");
                                FilterOperators.Add("Ends With");
                                FilterOperators.Add("Does Not End With");
                                break;
                            case AttributeTypeCode.Decimal:
                            case AttributeTypeCode.Double:
                            case AttributeTypeCode.Integer:
                            case AttributeTypeCode.Money:
                                FilterOperators.Add("Is Greater Than");
                                FilterOperators.Add("Is Greater That or Equal To");
                                FilterOperators.Add("Is Less Than");
                                FilterOperators.Add("Is Less Than or Equal To");
                                break;
                            case AttributeTypeCode.DateTime:
                                FilterOperators.Add("On Or After");
                                FilterOperators.Add("On Or Before");
                                break;

                            default:
                                break;
                        }
                        FilterOperators.Add("Contains Data");
                        FilterOperators.Add("Does Not Contain Data");



                        FilterAttributeSelectedEvent(this, null);

                    }
                    FilterOperator = "Equals"; //set default

                    RaisePropertyChanged("SelectedAttribute");
                    RaisePropertyChanged("SelectedAttribute");
                    RaisePropertyChanged("FilterOperators");
                    RaisePropertyChanged("FilterOperator");
                    RaisePropertyChanged("LogicalOperators");
                    RaisePropertyChanged("LogicalOperator");
                    RaisePropertyChanged("AttributeListVisibilityLevel");
                    RaisePropertyChanged("SelectFilterVisibilityLevel");
                    RaisePropertyChanged("TextValueVisibilityLevel");
                    RaisePropertyChanged("OptionSetValueVisibilityLevel");
                }
            }

        } private AttributeClass _attributeSelected;


        ObservableCollection<Item> _attributeValues;
        public ObservableCollection<Item> AttributeValues
        {
            get
            {
                if (_attributeSelected != null)
                {
                    if (_attributeValues == null)
                        _attributeValues = new ObservableCollection<Item>();
                    else
                        _attributeValues.Clear();

                    switch (_attributeSelected.AttributeType)
                    {
                        case AttributeTypeCode.Boolean:
                            BooleanAttributeMetadata b = (BooleanAttributeMetadata)_attributeSelected.Metadata;
                            _attributeValues.Add(new Item("false", b.OptionSet.FalseOption.Label.UserLocalizedLabel.Label));
                            _attributeValues.Add(new Item("true", b.OptionSet.TrueOption.Label.UserLocalizedLabel.Label));
                            break;
                        case AttributeTypeCode.Picklist:
                            PicklistAttributeMetadata p = (PicklistAttributeMetadata)_attributeSelected.Metadata;
                            foreach (OptionMetadata o in p.OptionSet.Options)
                                _attributeValues.Add(new Item(o.Value.ToString(), o.Label.UserLocalizedLabel.Label));
                            break;
                        case AttributeTypeCode.State:
                            StateAttributeMetadata state = (StateAttributeMetadata)_attributeSelected.Metadata;
                            foreach (OptionMetadata o in state.OptionSet.Options)
                                _attributeValues.Add(new Item(o.Value.ToString(), o.Label.UserLocalizedLabel.Label));
                            break;
                        case AttributeTypeCode.Status:
                            StatusAttributeMetadata status = (StatusAttributeMetadata)_attributeSelected.Metadata;
                            foreach (OptionMetadata o in status.OptionSet.Options)
                                _attributeValues.Add(new Item(o.Value.ToString(), o.Label.UserLocalizedLabel.Label));
                            break;


                    }
                }
                return _attributeValues;
            }

        }


        public ObservableCollection<string> FilterOperators
        {
            get { return _filterOperators; }
            set { if (_filterOperators != value) { _filterOperators = value; RaisePropertyChanged("FilterOperators"); RaisePropertyChanged("FilterOperator"); } }

        } private ObservableCollection<string> _filterOperators;

        public string FilterOperator
        {
            get { return _filterOperator; }
            set
            {
                _filterOperator = value;
                RaisePropertyChanged("TextValueVisibilityLevel");
                RaisePropertyChanged("OptionSetValueVisibilityLevel");
            }
        }


        public string AttributeListVisibilityLevel
        {
            get { return (SelectedAttribute == null) ? "Visible" : "Collapsed"; }
        }

        public string SelectFilterVisibilityLevel
        {
            get { return (SelectedAttribute != null) ? "Visible" : "Collapsed"; }
        }

        public string FilterActionsVisibilityLevel
        {
            get { return (FilterActions != null) ? "Visible" : "Collapsed"; }
        }

        public string LogicalOperatorVisibilityLevel
        {
            get { return (FilterActions == null) ? "Visible" : "Collapsed"; }
        }

        public string OptionSetValueVisibilityLevel
        {
            get
            {
                string visible = "Collapsed";
                if (_filterOperator != "Contains Data" && _filterOperator != "Does Not Contain Data")
                {

                    if (_attributeSelected != null)
                    {
                        switch (_attributeSelected.AttributeType)
                        {
                            case AttributeTypeCode.Boolean:
                            case AttributeTypeCode.Picklist:
                            case AttributeTypeCode.State:
                            case AttributeTypeCode.Status:
                                visible = "Visible";
                                RaisePropertyChanged("AttributeValues");
                                RaisePropertyChanged("Value");
                                break;
                        }
                    }
                }
                return visible;
            }
        }

        public string TextValueVisibilityLevel
        {
            get
            {
                string visible = "Collapsed";
                if (_filterOperator != "Contains Data" && _filterOperator != "Does Not Contain Data")
                {
                    if (_attributeSelected != null)
                    {

                        switch (_attributeSelected.AttributeType)
                        {
                            case AttributeTypeCode.BigInt:
                            case AttributeTypeCode.Customer:
                            case AttributeTypeCode.Decimal:
                            case AttributeTypeCode.Double:
                            case AttributeTypeCode.Integer:
                            case AttributeTypeCode.Lookup:
                            case AttributeTypeCode.ManagedProperty:
                            case AttributeTypeCode.Memo:
                            case AttributeTypeCode.Money:
                            case AttributeTypeCode.Owner:
                            case AttributeTypeCode.PartyList:
                            case AttributeTypeCode.String:
                            case AttributeTypeCode.Uniqueidentifier:
                            case AttributeTypeCode.Virtual:
                            case AttributeTypeCode.EntityName:
                            case AttributeTypeCode.DateTime:
                            case AttributeTypeCode.CalendarRules:
                                visible = "Visible";
                                RaisePropertyChanged("Value");
                                break;
                        }
                    }
                }
                return visible;
            }
        }

        public string[] FilterActions
        {
            get
            {
                if (IsPrimaryGroupAttribute)
                {
                    _filterActions = new string[2];

                    _filterActions[0] = "Ungroup";
                    _filterActions[1] = "Delete";
                }
                else
                {
                    if (String.IsNullOrEmpty(GroupLogicalOperator))
                    {
                        _filterActions = new string[2];
                        if (IsSelected)
                            _filterActions[0] = "Deselect";
                        else
                            _filterActions[0] = "Select";

                        _filterActions[1] = "Delete";
                    }
                    else
                    {
                        _filterActions = null;
                    }

                }
                return _filterActions;
            }

        } private string[] _filterActions;

        public string FilterAction
        {
            set
            {
                if (value != null && FilterAction != value)
                {
                    switch (value)
                    {
                        case "Select":
                            IsSelected = true;
                            RaisePropertyChanged("IsSelected");
                            RaisePropertyChanged("RowColour");
                            break;
                        case "Deselect":
                            IsSelected = false;
                            RaisePropertyChanged("IsSelected");
                            RaisePropertyChanged("RowColour");
                            break;
                        case "Ungroup":
                            UnGroupFiltersEvent(this, null);
                            break;
                        case "Delete":
                            DeleteFilterEvent(this, null);
                            break;
                    }

                    RaisePropertyChanged("FilterAction");
                    RaisePropertyChanged("FilterActions");
                }

            }
            get { return null; }
        }


        public string GroupLogicalOperator
        {
            set
            {
                if (_groupLogicalOperator != value)
                {
                    _groupLogicalOperator = value;

                    RaisePropertyChanged("RowColour");
                    RaisePropertyChanged("FilterActions");
                    RaisePropertyChanged("FilterAction");
                    RaisePropertyChanged("SelectedAttribute");
                    RaisePropertyChanged("FilterOperators");
                    RaisePropertyChanged("FilterOperator");
                    RaisePropertyChanged("AttributeListVisibilityLevel");
                    RaisePropertyChanged("SelectFilterVisibilityLevel");
                    RaisePropertyChanged("FilterActionsVisibilityLevel");
                    RaisePropertyChanged("LogicalOperatorVisibilityLevel");
                    RaisePropertyChanged("GroupLogicalOperator");
                }
            }
            get
            {
                return _groupLogicalOperator;
            }
        }


        public string RowColour
        {
            get
            {
                return (IsSelected) ? "#FFBADDE9" : "White";
            }
        }

    }

}
